#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
#include<sstream>
#include<vector>
#include<map>
#include<set>
using namespace std;

class TextQuery
{
public:
	typedef vector<string>::size_type LineNo;
	void ReadFile(ifstream &is)
	{
		StoreFile(is);
		BuildMap();
	}
	set<LineNo> RunQuery(const string &s)
	{
		map<string,set<LineNo> >::iterator loc=wordMap.find(s);
		if(loc==wordMap.end())return set<LineNo>();
		else return loc->second;
	}
	string TextLine(LineNo line) const
	{
		if(line<linesOfText.size())return linesOfText[line];
		throw out_of_range("line number out of range");
	}
private:
	void StoreFile(ifstream &is)
	{
		string textLine;
		while(getline(is,textLine))
			linesOfText.push_back(textLine);
	}
	void BuildMap()
	{
		istringstream line;
		string word;
		for(LineNo lineNum=0;lineNum!=linesOfText.size();lineNum++)
		{
			line=istringstream(linesOfText[lineNum]);
			while(line>>word)wordMap[word].insert(lineNum);
		}
	}
	vector<string> linesOfText;
	map<string,set<LineNo> > wordMap;
protected:
	int text;
};
class Text:public TextQuery
{
public:
	Text()
	{
		text=2;
	}
};
string MakePlural(size_t ctr,const string &word,const string &ending)
{
	return (ctr<=1)?word:word+ending;
}
void PrintResult(set<TextQuery::LineNo> locs,string s,TextQuery tq)
{
	typedef set<TextQuery::LineNo> LineNums;
	LineNums::size_type size=locs.size();
	cout<<s<<" occurs "<<size<<" "<<MakePlural(size,"time","s")<<endl;
	for(LineNums::iterator it=locs.begin();it!=locs.end();it++)
	{
		cout<<"	(line "<<*it+1<<" ) "<<tq.TextLine(*it)<<endl;
	}
}
int main()
{
	ifstream infile;
	infile.open("e:\\1.txt");
	TextQuery tq;
	tq.ReadFile(infile);
	string s;
	while(true)
	{
		cout<<"Enter a word to look for,or q to quit:";
		cin>>s;
		if(!cin||s=="q")break;
		set<TextQuery::LineNo> locs=tq.RunQuery(s);
		PrintResult(locs,s,tq);
	}
	return 0;
}
